home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 8
/
The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO
/
dosutils
/
tsbat50.zip
/
BATRICKS.TXT
< prev
next >
Wrap
Internet Message Format
|
1996-09-01
|
52KB
From ts@uwasa.fi Sun Sep 1 00:00:00 1996
Subject: Batchtricks file information
Assorted Batch Tricks Sun 1-September-1996
=====================
All rights reserved
Copyright (c) 1993-1996 by Timo Salmi
....................................................................
Prof. Timo Salmi Co-moderator of news:comp.archives.msdos.announce
Moderating at ftp:// & http://garbo.uwasa.fi archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
ts@uwasa.fi http://uwasa.fi/~ts BBS 961-3170972; FIN-65101, Finland
....................................................................
┌───────────────────────────────────────────────────────────┐
│ This file belongs to TSBAT*.ZIP. Please do not distribute │
│ this batricks.txt file separately! If you see this file │
│ alone on a BBS, please alert the SysOp immediately. │
└───────────────────────────────────────────────────────────┘
Introduction
============
This file contains assorted batch tricks. The items are in no
particular order. Many, but not all, have been used in the
TSBAT*.ZIP collection of batches. Likewise, there are some useful
further tricks, not documented here, to be found in the TSBAT
batches. Furthermore, many users have sent me useful suggestions and
their own alternative solutions. My best thanks for the material.
You can find much of this feedback and the other users' solutions
stored in the ftp://garbo.uwasa.fi/pc/pd2/tspost*.zip files. For
further batch programming material via the World Wide Web use
http://garbo.uwasa.fi/pc/batchutil.html. Also, connect to my home
page http://uwasa.fi/~ts/ then click my collection of HTTP links and
find the section on programming.
You are free to quote brief passages from this BATRICKS.TXT file
provided you clearly indicate the source with a proper
acknowledgment.
Comments and corrections are solicited. But if you wish to have
individual batch programming consultation, please rather post your
question to a Usenet newsgroup like news:comp.os.msdos.programmer or
news:alt.msdos.batch. It is much more efficient than asking me by
email. I'd like to help, but I am very pressed for time. I prefer to
pick the questions I answer from the Usenet news. Thus I can answer
publicly at one go if I happen to have an answer. Besides,
newsgroups have a number of readers who might know a better or an
alternative answer. Don't be discouraged, though, if you get a reply
like this from me. I am always glad to hear from fellow batch file
users.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:01 1996
Subject: Batch tricks index
INDEX
=====
1) Making "@echo off" MS-DOS version independent
2) Deleting all files without being prompted
3) Nested for loops in batch files
4) Checking whether a directory exists
5) Checking that a program is available at the current directory or at path
6) Using subroutines and recursion in batches
7) Convert a parameter to uppercase
8) Appending a new directory to the path
9) Comparing two files
10) Writing an empty line
11) Customizing the pause message
12) Complicated renaming of files with for
13) Checking a file name for wildcards
14) Preventing breaking the batch
15) Prevent a break from bypassing your autoexec.bat
16) Getting the file name extension
17) The quote character %
18) Eliminating auxiliary batches
19) Utilizing the subst command in paths
20) How to run a batch once a week (testing for the weekday)
21) Testing if a file name includes a path
22) Showing the time without enter
23) Alternatives for testing for the errorlevel value
24) Redirecting a batch file's output
25) Testing for environment space sufficiency
26) A simple trick to "disable" a drive
27) Sending an escape sequence to the printer
28) Creating a random string
29) Finding out the length of a string
30) How to obtain the MS-DOS version into an environment variable
31) Finding out the number of regular files on a drive
32) Augmenting line numbers to a text file
33) Storing and returning to the original directory (push and pop)
34) Enticing the current date into an environment variable
35) Identifying the individual PC
36) For loop and redirection quirks
37) Traversing a directory tree
38) Echoing the redirection symbol
39) Getting the file basename
40) A batch to put user input into an environment variable
41) Getting the last replaceable parameter
42) Creating an empty file if the file does not already exist
43) How can I change or remove the disk volume serial number?
44) How to pause in a batch for a preset number of seconds?
45) Where can I find a program to compile batches into COMs or EXEs?
46) How can I test whether a disk is empty or not?
47) How can I run a different batch depending on the weekday?
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:02 1996
Subject: Generalizing @echo off
1. Making "@echo off" MS-DOS version independent
================================================
If you want to turn the echo off, and do not wish to show that line
on the screen, you can easily do this by applying
@echo off
There is a catch, however, because this only works since MS-DOS
version 3.30. So if you want to make it general, put the following
line in your autoexec.bat file if you are using MS-DOS 3.30 or
higher
set _echo=@
Then use the following format in your batches, which will then work
for any MS-DOS version
%_echo%echo off
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:03 1996
Subject: Deleting all files
2. Deleting all files without being prompted
============================================
One of the most Frequently Asked Questions (FAQs) about batches is
how to suppress the "Are you sure (Y/N)?" confirmation requirement
for del *.*. Use the following:
echo y| del *.*
If you wish to suppress the message too, use
echo y| del *.* > nul
There is also another alternative for doing this:
for %f in (*.*) do call del %f
Whether or not it is sensible to suppress the confirmation can be
debated, but these are the tricks anyway.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:04 1996
Subject: Nested for loops
3. Nested for loops in batch files
==================================
It is possible to have nested loops of a kind in batch programming.
Consider the following two batches, and try it out by calling
test.bat.
echo off
rem TEST.BAT
for %%f in (a b c d e f) do %comspec% /c test2 %%f
echo off
rem TEST2.BAT
for %%g in (1 2 3) do echo %1%%g
Alternatively write everything below on a single line
for %%f in (a b c d e f) do %comspec% /c
for %%g in (1 2 3) do echo %%f%%g
(The wrap has been used in the text is because of the right margin.
Don't wrap your batch.). The disadvantage of this alternative is
that the echo will be on.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:05 1996
Subject: Checking directory existence
4. Checking whether a directory exists
======================================
It is sometimes useful to be able to test whether a particular
directory exists. The following test is true if the %1 directory
does not exist.
if not exist %1\nul if not exist %1nul echo Directory %1 does not exist
Please note that just like many other items, this will not work on
4DOS or DR-DOS. These otherwise excellent alternatives have many
hidden incompatibilities with vanilla MS-DOS. Furthermore, this does
not seem to work for a CD-ROM. Probably because of the CD-ROM
drivers use a slightly different directory system with no . (dot)
and .. (dot-dot). My thanks to Bjorn Svensson for bringing this to
my attention.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:06 1996
Subject: Checking program existence
5. Checking that a program is available at the current directory or at path
===========================================================================
When you call a program from a batch, and do not give the explicit
path to it, it is advisable to test that the program is available
either at the current directory or the default path.
set _found=
if exist %1 set _found=yes
for %%d in (%path%) do if exist %%d\%1 set _found=yes
for %%d in (%path%) do if exist %%d%1 set _found=yes
if "%_found%"=="yes" goto _continue
echo %1 is not at path or the current directory
goto _out
:_continue
echo %1 found at path or in the current directory
:_out
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:07 1996
Subject: Subroutines and recursion
6. Using subroutines and recursion in batches
=============================================
It is possible to use subroutines within batches. The crucial trick
is setting an environment variable (e.g. _return) to point to a
label where to return after the subroutine has been performed. For
an example see UNPACK.BAT, and BOOT.BAT, the sections :_common and
:_subru.
Likewise it is possible to use recursion go emulate subroutines in
batches. (Recursion means that a batch calls itself).
As an example see SAFEDEL.BAT and trace the effects of the line
for %%f in (%1) do call safedel %%f recurse
Note that safedel could be replaced by %0 because the zeroth
parameter of a batch file points to itself.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:08 1996
Subject: Coversion to uppercase
7. Convert a parameter to uppercase
===================================
This example shows how to ensure that the parameter %1 given to the
batch is in uppercase. This utilizes the fact that MS-DOS converts
the path to uppercase. The result is stored in upcase_ and then the
original path is restored.
set tmp_=%path%
path=%1
set upcase_=%path%
path=%tmp_%
set tmp_=
The also is another method for getting case-independent results.
This is adapted from Jeff Prosise's column in PC Computing, March
1993, pp. 216-217. If the batch below is called TEST.BAT, it makes
no difference whether you enter "TEST yes" or "TEST YES" or "TEST
yEs".
@echo off
if not "%1"=="" set %1=*****
set status_=
if "%yes%"=="*****" set status_=yes
if "%no%"=="*****" set status_=no
if not "%status_%"=="" echo The parameter %%1 was a %status_%
if "%status_%"=="" echo The parameter %%1 was neither a yes nor a no
if not "%1"=="" set %1=
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:09 1996
Subject: Append new directory to path
8. Appending a new directory to the path
========================================
This often needed trick is basically very simple. For example
to add directory %1 to path use
path=%path%;%1
Note that you can only use this trick in a batch. It will not work
at the MS-DOS prompt because the environment variables are expanded
(%path%) only within batches.
For a full treatment with safeguards against appending non-existing
directories, or appending twice, see ADDPATH.BAT.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:10 1996
Subject: Comparing two files
9. Comparing two files
======================
It is possible in batch programming to test whether or not two files
have identical contents. This trick utilizes the external MS-DOS
programs fc.exe and find.exe. (An external MS-DOS program means, of
course, a program that comes with the standard MS-DOS releases. Most
often the MS-DOS external support files are located in a c:\dos
directory.)
fc %1 %2 > tmp$$$
type tmp$$$ | find /i "fc: no differences encountered" > diffe$$$
if exist notsame$ del notsame$
copy diffe$$$ notsame$ > nul
if not exist notsame$ echo Files %1 and %2 are different
if exist notsame$ echo Files %1 and %2 are identical
if exist tmp$$$ del tmp$$$
if exist notsame$ del notsame$
if exist diffe$$$ del diffe$$$
If you think about, this idea can be used for other useful purposes,
too, because it establishes whether a given string is found in a
text file.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:11 1996
Subject: Writing an empty line
10. Writing an empty line
=========================
This is a simple, but an often needed, useful trick. Just use echo
with (for example) a point (.) after it. As you can see, I have
utilized this batch feature extensively in my batch collection.
echo.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:12 1996
Subject: Customizing the pause message
11. Customizing the pause message
=================================
You can easily customize the message given by pause by giving your
own with echo and directing the pause message to nul.
to nul.
echo Break to quit, any other key to remove the tmp directory
pause > nul
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:13 1996
Subject: Complicated renaming with for
12. Complicated renaming of files with for
==========================================
Although this is basically trivial, one does not necessarily come to
think of it. The for statement is quite useful for involved renaming
of files. An example delineates. For example I have the following
files (Turbo Pascal units for TP 4.0, 5.0, 5.5, 6.0 and 7.0). Say
that I wish to rename them to be version 33 instead of 32.
tspa3340.zip
tspa3350.zip
tspa3355.zip
tspa3360.zip
tspa3370.zip
The following for-statement does that conveniently.
for %f in (40 50 55 60 70) do ren tspa32%f.zip tspa33%f.zip
Naturally, renaming is not the only task that can utilize this
trick. I am sure you can readily think of others, like
for %d in (a b) do format %d:
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:14 1996
Subject: Checking for wildcards
13. Checking a file name for wildcards
======================================
This example shows how you can test whether a parameter (%1) of a
batch contains wildcards.
@echo off
for %%f in (%1) do if "%%f"=="%1" goto _nowilds
echo Parameter %1 contains wildcards (or is missing)
:_nowilds
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:15 1996
Subject: Preventing breaking the batch
14. Preventing breaking the batch
=================================
It is possible to prevent the user from interrupting a batch by
using the ctty command to reassign the input (and the output)
device. Here is an example (an elementary password batch requiring
inputting an e). Note the < and > redirections which are needed
while the ctty has been assigned to nul. The ask batch enhancer is
included in the TSBAT collection.
@echo off
ctty nul
echo Now you cannot break the batch with ^C or ^Break > con
:_ask
echo Use e to break > con
ask /b /d < con
if errorlevel==101 if not errorlevel==102 goto _out
goto _ask
:_out
ctty con
echo Back to normal. Now you can break the batch with ^C or ^Break.
Note that this trick does not prevent you from rebooting with
alt-crtl-del while the batch is running. For that you need an
external program like noboot.exe from
86523 Aug 7 1994 ftp://garbo.uwasa.fi/pc/ts/tstsr20.zip
tstsr20.zip TSR programs (noboot,reslock,sordino,timedown,timeup ...)
(or whichever version number is current).
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:16 1996
Subject: Forcing autoexec.bat execution
15. Prevent a break from bypassing your autoexec.bat
====================================================
You can actually prevent a quick tapping of the break from bypassing
your autoexec.bat by a variation of the trick in the item above. Put
for example
shell=c:\command.com /p nul
in your config.sys. Before you do, make sure to have a floppy to
boot from in case something goes wrong. I first saw trick when it
was posted in the Usenet news:comp.os.msdos.programmer newsgroup by
Joseph Gil yogi@cs.ubc.ca.
This is not, however, quite all there is to it. You should put
ctty con
as the last line to your autoexec.bat. If you don't, the keyboard
will not be responding, and you must boot from the floppy you so
sensibly had prepared :-).
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:17 1996
Subject: Getting the extension
16. Getting the file name extension
===================================
It would be quite useful to be able to extract the extension of a
given file name into an environment variable. Or to be able just to
test whether there is an extension. Here is how to do that. The
batch is based on the information in PC-Magazine July 1992, Vol. 11,
No. 13, page 528. It gives the crucial information that if one
precedes the argument of a for loop with a slash (/), then the
argument is interpreted in two parts. The first part is the first
character of the argument, the second part all the rest. Neat,
indeed.
The problem with my solution below is that it will not recognize
.* or .??? as extensions. But, of course, one can first test for
wildcards as shown in a previous item "Checking for wildcards". See
e.g. UNPACK.BAT for the utilization of this method.
@echo off
set exten_=%1
:_next
set prev_=%exten_%
for %%f in (/%exten_%) do set exten_=%%f
if ".%exten_%"=="%prev_%" goto _extfound
if not "%exten_%"=="%prev_%" goto _next
goto _noext
:_extfound
echo The filename %1 has an extension %exten_%
goto _out
:_noext
echo The filename %1 has no extension
:_out
set exten_=
set prev_=
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:18 1996
Subject: The quote character %
17. The quote character %
=========================
As we know %1 indicates the first parameter given to a batch. Thus
for example echo %1 echoes that parameter. But what if you want to
echo the actual string %1 instead. The % character acts as a quote
character. Thus echo %%1 will indeed be a "%1" instead of its usual
interpretation. Try the following simple test
@echo off
if "%1"=="" goto _out
echo %1
echo %%1
:_out
See the item on "Eliminating auxiliary batches" for utilizing this
feature. A good example of utilizing this feature is given by
DELPATH.BAT.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:19 1996
Subject: Eliminating auxiliary batches
18. Eliminating auxiliary batches
=================================
Quite a number of batch programming tasks require an auxiliary batch
which the primary batch has to call. Many of these cases can be
eliminated by making the batch call itself (a kind of recursion).
The auxiliary code is put in the batch itself. The trick is best
illustrated by looking at the SHOW.BAT, which provides a wild-carded
TYPE command, and would normally need an auxiliary file to type each
of the individual files. Another example is given by the SAFEDEL.BAT
batch.
There is also an another trick for a similar purpose. The primary
batch creates and auxiliary batch or batches, which it then calls.
See DELPATH.BAT for an example of this method. Here is also a simple
demonstration listing the drives on your system. (Only from c to t,
actually because of the wrap I use here).
@echo off
echo @echo off> tmp$$$.bat
echo if exist %%1:\nul echo Drive %%1: is present>> tmp$$$.bat
for %%d in (c d e f g h i j k l m n o p q r s t) do call tmp$$$ %%d
del tmp$$$.bat
There was an inventive twist of this method in PC-Magazine August
1992, Vol. 11, No. 14, p. 527 for getting the volume label of a
disk. Here is my own example using the same techniques. It sets the
current directory in an environment variable getdir_. I have
utilized this technique in PUSHDIRE.BAT.
@echo off
echo @echo off> director.bat
echo set getdir_=%%2>> director.bat
echo echo %%getdir_%%>> director.bat
dir | find "Directory"> go.bat
call go
if exist director.bat del director.bat
if exist go.bat del go.bat
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:20 1996
Subject: Subst utilization in paths
19. Utilizing the subst command in paths
========================================
I use the following kind of a simple batch to make some of my
directories easy to reach. The way this simple batch is written it
avoids unnecessary errors if the substitution already has been made.
As a last measure it shows the current substitution status.
@echo off
if exist m:\nul echo The substitution has already been made
if not exist m:\nul subst m: c:\math
if not exist s:\nul subst s: c:\support
subst
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:21 1996
Subject: Run a batch one a week
20. How to run a batch once a week (testing for the weekday)
============================================================
The crucial trick is to be able to put the weekday into an
environment variable. For the full treatment see WEEKLY.BAT. The
essential trick needed is below, that is capturing the weekday into
a weekday_ environment variable. No auxiliary programs outside the
normal MS-DOS commands are needed.
@echo off
echo.| date | find "Current" > tmp$$$.bat
echo set weekday_=%%3> current.bat
call tmp$$$
echo %weekday_%
if "%weekday_%"=="Fri" echo Thank God it's Friday
if exist tmp$$$.bat del tmp$$$.bat
if exist current.bat del current.bat
set weekday_=
In fact, if you substitute %%4 for the %%3 in the above, you'll
capture today's date. Neat, eh?
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:22 1996
Subject: Is path included in file name?
21. Testing if a file name includes a path
==========================================
First of all please see the earlier item "Getting the extension"
because the same ideas are drawn upon. Testing whether the file name
is a bare file name like go.exe or includes a path like
r:\progs\go.exe is quite a complicated task if one wants to allow
wildcarded names like r:\progs\*.exe. This can be done, and here is
how. If one can figure this one out, one can safely say that one has
begun to understand batch files.
@echo off
echo @echo off> tmp$$$.bat
echo set rest_=%%1>> tmp$$$.bat
echo :_next>> tmp$$$.bat
echo set prev_=%%rest_%%>> tmp$$$.bat
echo for %%%%g in (/%%rest_%%) do set rest_=%%%%g>> tmp$$$.bat
echo if ":%%rest_%%"=="%%prev_%%" goto _found>> tmp$$$.bat
echo if "\%%rest_%%"=="%%prev_%%" goto _found>> tmp$$$.bat
echo if not "%%rest_%%"=="%%prev_%%" goto _next>> tmp$$$.bat
echo goto _nopath>> tmp$$$.bat
echo :_found>> tmp$$$.bat
echo set haspath_=yes>> tmp$$$.bat
echo goto _out>> tmp$$$.bat
echo :_nopath>> tmp$$$.bat
echo set haspath_=no>> tmp$$$.bat
echo :_out>> tmp$$$.bat
echo set rest_=>> tmp$$$.bat
echo set prev_=>> tmp$$$.bat
for %%f in (%1) do call tmp$$$ %%f
if "%haspath_%"=="yes" echo Filename %1 includes a path
if "%haspath_%"=="no" echo Filename %1 does not include a path
rem if exist tmp$$$.bat del tmp$$$.bat
set haspath_=
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:23 1996
Subject: Display the time
22. Showing the time without enter
==================================
A simple trick to show the current time:
echo.| time | find /v "new"
For capturing the time into an environment variable see
LASTBOOT.BAT.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:24 1996
Subject: Testing for the errorlevel
23. Alternatives for testing for the errorlevel value
=====================================================
Many programs and some MS-DOS commands (like diskcomp, format and
xcopy) return an errorlevel exit code on termination. Testing for
the errorlevel is complicated by the cumulative nature of
errorlevels. Thus if you wish to test if the errorlevel was
(exactly) 2, you must use
if errorlevel==2 if not errorlevel==3 echo Errorlevel 2
Another alternative is utilizing the for command:
for %%e in (0 1 2 3 4 5 6 7) do if errorlevel==%%e set _errlev=%%e
if "%_errlev%"=="2" echo Errorlevel 2
Alternatively, and more generally
for %%e in (0 1 2 3 4 5 6 7) do if errorlevel==%%e set _errlev=%%e
if "%_errlev%"=="2" echo Errorlevel %_errlev%
A convenient trick in more complicated batches is using the goto
command:
for %%e in (0 1 2) do if errorlevel==%%e goto _label%%e
goto _out
:_label0
echo Errorlevel 0
:_label1
echo Errorlevel 1
:_label2
echo Errorlevel 2
:_out
See BOOT.BAT for actual usage of this technique.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:25 1996
Subject: Redirecting bacth output
24. Redirecting a batch file's output
=====================================
Output from within a batch file is easily redirected. Consider a
batchfile example.bat with the following contents
@echo This is a redirection test> test
Running "example" will produce a file "test" with
This is a redirection test
The line has an eoln (end of line: ascii 13 + 10) at the end.
Note that it often is advisable not to leave any blank in front of
the > redirection operator.
Redirecting the output that a batch produces, is more complicated.
Consider a batchfile example2.bat with the following contents
@echo This is another redirection test
Running
example2 > test
will produce an empty "test" file, while the text is echoed on the
standard output. To redirect the output, you need to drive the batch
through the command interpreter command.com like this (provided that
command.com is at path or in the current directory).
command /c example2 > test
This will redirect the text to the "test" file.
There is another quirk of redirection in MS-DOS batch programming
best demonstrated by an example:
@echo off
rem This line will create an empty tmp.$$ file > tmp.$$
:: This line will not create an empty tmp.$$$ file > tmp.$$$
rem This line will cause problems: Press <ESC>
:: This line will not cause problems: Press <ESC>
As explained in PC Magazine Vol 12, Number 9, November 9, 1993, the
reason is that the :: is taken as a label and not processed while
the rem basically is an MS-DOS command that will be processed. The
processing will start from the redirection at the end. This is the
the also reason why redirection and the MS-DOS FOR command will
cause problems. (See the entry "For loop and redirection quirks".)
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:26 1996
Subject: Out of environment space
25. Testing for environment space sufficiency
=============================================
If your batch utilizes environment variables there is a possibility
that you run out of environment space. If you get an "Out of
environment space" message the well-known trick to increase your
environment space by using shell configuration in config.sys:
Example: shell=c:\bin\command.com c:\bin /e:1024 /p
A perhaps less-known trick is that you can test in advance if your
batch will run out of environment space. Below is an example showing
you how to test if you have an additional 32 bytes of environment
space still available for your batch:
@echo off
set test_=12345678901234567890123456789012
if "%test_%"=="12345678901234567890123456789012" goto _yes
echo Insufficient environment space
goto _out
:_yes
echo Sufficient environment space
set test_=
rem Whatever you wish to do
:_out
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:27 1996
Subject: Disabling a drive
26. A simple trick to "disable" a drive
=======================================
It you wish temporarily disable a drive use the subst command for
example as follows
@echo off
md c:\none
subst d: c:\none
To enable it again use
@echo off
subst d: /d
rd c:\none
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:28 1996
Subject: Escape sequence to printer
27. Sending an escape sequence to the printer
=============================================
Here is a truly trivial trick. You cannot send escape sequences to
the printer directory from the command line, but it is quite easy to
do that from a simple batch file:
@echo ESC%1> prn
where you have to replace the ESC by the true escape character using
your preferred editor. One snag with this methods is that it imposes
a linefeed.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:29 1996
Subject: Creating a random string
28. Creating a random string
============================
I was asked on the UseNet news how to create a random string. My
reply. Please study the following example and expand on it
@echo off
echo 10 randomize(val(mid$(time$,7,2))) > tmp.bas
echo 20 open "tmp2.bat" for output as #1 >> tmp.bas
echo 30 x$ = mid$(str$(int(rnd*10000)),2) >> tmp.bas
echo 40 print #1,"@set random_=";x$ >> tmp.bas
echo 50 close #2 >> tmp.bas
echo 60 system >> tmp.bas
gwbasic tmp.bas
call tmp2
del tmp.bas
del tmp2.bat
set
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:30 1996
Subject: Getting string length
29. Finding out the length of a string
======================================
The task of finding out the length of a string was tackled in PC
Magazine January 26, 1993 issue. The solution is my own and more
general, but naturally it has similar ingredients to the PC
Magazine's.
@echo off
set test_=Testing the length of a string
echo %test_% > len$&$&$
dir len$&$&$ | find "LEN$&$&$" > go$$$.bat
echo @echo off> len$&$&$.bat
echo set length_=%%1>> len$&$&$.bat
call go$$$
echo The length is %length_% bytes
del len$&$&$
del len$&$&$.bat
del go$$$.bat
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:31 1996
Subject: MS-DOS version into environment variable
30. How to obtain the MS-DOS version into an environment variable
=================================================================
Here is the code how to do it.
@echo off
ver > go$$$.bat
echo @echo off> ms-dos.bat
echo set version_=%%2>> ms-dos.bat
call go$$$
echo Your MS-DOS version is %version_%
del go$$$.bat
del ms-dos.bat
MS-DOS 5.0 version introduced many enhancements (like the loadhigh
command, etc) and additions to the command switches (like /B and /S
to the DIR command). Therefore it is useful to be able to test
whether the batch is being run on a system that is at least MS-DOS
5.0. Below is one option.
rem Establish whether MS-DOS version 5.0 or later is being used
set isver50_=
ver | find "5.0" > tmpfind.$$$
ver | find "6.0" >> tmpfind.$$$
ver | find "6.2" >> tmpfind.$$$
copy tmpfind.$$$ tmpfind1.$$$ > nul
del tmpfind.$$$
if exist tmpfind1.$$$ set isver50_=yes
if exist tmpfind1.$$$ del tmpfind1.$$$
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:32 1996
Subject: Number of files on a drive
31. Finding out the number of regular files on a drive
======================================================
Try
attrib /s c:\*.* | find /c "\"
The directories will not be (mis)counted as files as would with the
dir command. Besides the dir command is not recursive until MS-DOS
version 5.0.
Note that if you do this for the same drive where you reside,
you'll get one too many in the count because of the "|" pipe.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:33 1996
Subject: Numbering a file's lines
32. Augmenting line numbers to a text file
==========================================
Occasionally it might be useful to put line number to a text file.
Here is an example how to do it with MS-DOS commands only
type YourFile.txt | find /v /n "&$&$&$123" > YourNew.txt
The parameter &$&$&$123 stands for an improbable string, since find
/v means displaying all the lines not containing it.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:34 1996
Subject: Push and pop a directory
33. Storing and returning to the original directory (push and pop)
=================================================================
There are several methods for (non-resident) pushing and popping the
directory by batch file techniques. In other words storing the
current directory, changing the directory in between, and then
returning to the starting directory. PUSHDIRE.BAT and POPDIRE.BAT
give one method where the current drive and directory are stored in
environment variables. The second method, displayed below, is a
direct adaptation from Jeff Prosise's column in PC Computing, March
1993, pp. 216-217. Later the trick was presented again in Pc
Magazine June 14, 1994, Vol. 13, No. 11, p. 357. The method is a
very clever utilization of the prompt system. An example
illustrates.
@echo off
echo @prompt cd $p$_$n:> r:\setback.bat
%comspec% /c r:\setback> r:\goback.bat
::
rem Change the drive and directory
c:
cd \dos
echo The current directory is
cd
rem Do whatever you wish to do there
pause
::
rem Go back to the original drive and directory
call r:\goback
echo Now back in the original directory
::
rem cleanup
if exist r:\setback.bat del r:\setback.bat
if exist r:\goback.bat del r:\goback.bat
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:35 1996
Subject: Date into environment variable
34. Enticing the current date into an environment variable
==========================================================
Like in the item "Storing and returning to the original directory"
there are more than one way of doing this. One method is indicated
in the item "How to run a batch once a week". The other (again)
utilizes the prompt:
@echo off
echo @prompt set date_=$d> r:\tmp$$$.bat
%comspec% /c r:\tmp$$$> r:\tmp2$$$.bat
call r:\tmp2$$$
echo %date_%
del r:\tmp$$$.bat
del r:\tmp2$$$.bat
If you look at your MS-DOS manual for the prompt special $ codes
(like $d) that you can use in the prompt, you'll see that this
method opens quite a number of possibilities of putting information
into environment variables. Exercise: Put the current weekday into
an environment variable. Hint: Apply $d and $h.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:36 1996
Subject: Identifying the individual PC
35. Identifying the individual PC
=================================
In cases of some batches it is useful to identify the PC the batch
is run on. For example I use several different PCs myself and
occasionally I need to differentiate between them. The solution is
really trivial. Set an environment variable in the autoexec.bat to
designate the PC. I use a variable pcid_ for this purpose. An
outline batch illustrates.
@echo off
if "%pcid_%"=="" goto _none
goto %pcid_%
:dell
echo Dell 325N laptop, do whatever
goto _out
:trifu
echo Trifunic 386 desktop, do whatever
goto _out
:karvi
echo "Garfunkel" Pinus 486 desktop, do whatever
goto _out
:_none
echo PC not identified, do whatever
:_out
For example in the autoexec.bat of my DELL 325N laptop I have
set pcid_=dell
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:37 1996
Subject: For loop and redirection
36. For loop and redirection quirks
===================================
A question from the Usenet newsgroups news:comp.os.msdos.misc and
news:comp.os.msdos.programmer:
> I am using DOS 5.0 and I have the following line in my batch file:
> for %%f in (a b c d) do if exist %%f echo put %%f >> tmpfile
> where a,b,c,d are some filenames.
>
> What I expect it to do is to echo the lines
> put a
> put b
> put c
> put d
> into the file tmpfile.
>
> But what happen is after the "put a" is written to tmpfile, the rest of the
> lines will just echo to the screen, look like that the redirection is not
> working.
>
> If I take away the "if exist" everything is working fine. I found out
> every time when I use a conditional statement with redirection, it will
> only redirect the first time, the rest will echo to the screen.
>
> Is it the for loop cannot be mixed with the conditional statement and the
> redirection?
Yes, it can be mixed, but not so simply in this case. Use the
following batch
@echo off
del tmpfile
for %%f in (a b c d) do if exist %%f call auxil %%f
where auxil.bat contains
@echo off
echo put %1>> tmpfile
I'll be darned if I know why :-).
In fact it is possible to do this with a single batch by employing
the following method described in an earlier item
@echo off
echo @prompt echo put %%%%1$g$g tmpfile> tmp$$$.bat
%comspec% /c tmp$$$> auxil.bat
if exist tmpfile del tmpfile
for %%f in (a b c d) do if exist %%f call auxil %%f
del tmp$$$.bat
del auxil.bat
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:38 1996
Subject: Traversing a directory tree
37. Traversing a directory tree
===============================
Traversing it straight up is relatively easy as can be seen from
this example.
@echo off
:_loop
dir/w
if not exist ..\nul goto _out
cd ..
goto _loop
:_out
Going recursively down through a directory and its subdirectories is
very complicated. Yet it can be done if you have MS-DOS 5.00 or
beyond. The SWEEP.BAT batch accompanying tsbat*.zip demonstrates
how. The method is, however, too difficult to be of real practical
importance. It is getter to use an auxiliary program for sweeping,
like ftp://garbo.uwasa.fi/pc/filefind/target15.zip or SWEEP.COM from
ftp://garbo.uwasa.fi/pc/pcmagvol/vol4n24.zip.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:39 1996
Subject: Echoing the > and >> symbols
38. Echoing the redirection symbol
==================================
In certain situations would be useful to be able echo the
redirection symbol rather than have its perform its redirection
function. For example your batch file might have a help line like
this
echo The line to customize is "echo dir/w %%%%3\%%2 >> %%new_%%"
As you see the double quotes pre-empt the redirection. If you left
them out, the line would result create a file %NEW_% containing
"The line to customize is echo dir/w %%3\%2".
Contrary to Unix, \ cannot be used to cover the special meaning
of a symbol. As explained in the item "The quote character %" the %
sign, can as is demonstrated above by the %% pairs. But %> does not
take precedence over the redirection.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:40 1996
Subject: Getting the file basename
39. Getting the file basename
=============================
Occasionally one needs to get the file name without the extension.
Just like getting the extension from a file name using the "for %%f
in (/%exten_%)" trick, even this can be done with batch commands
only. The batch code for getting the basename has been presented by
Neil Rubenking in PC Magazine April 26, 1994, Vol. 13, No. 8, pp.
275-276. But enough is enough even with batch tricks. The logic is
getting overly complicated. One has to draw the line somewhere, stop
kidding oneself, and start using batch enhancers (external programs
to help out). I think here the limit has been reached. Hence I have
included "basename" and "basepath" programs, which you can use to
create the enhancers. They return the relevant information into an
environment variable with that name.
When you come to think of it. From one viewpoint, what else than
batch enhancers are all the external MS-DOS commands (usually) in
your C:\DOS directory?
Using basename and basepath is very easy. Below is an example
@echo off
basename r:\cmand\command.com
basepath r:\cmand\command.com
echo %basename%
echo %basepath%
You can discard the environment variable simply by applying (note
the two alternatives):
set basename=
basepath
There is also a "basexten" batch enhancer in the /pc/ts/tsbat*.zip
collection.
A batch-only solution is presented below. It owes heavily to a
posting by Ted Davis tdavis@umr.edu in news:alt.msdos.batch.
@echo off
::
rem Instructions
if "%1"=="" goto _usage
::
rem Create an auxiliary directory
mkdir tmpaux$$
::
rem Create an empty auxiliary file
rem > tmpaux$$\%1
::
rem Go to the auxiliary directory
cd tmpaux$$
::
rem Rename the file without extension (this is the trick!)
ren %1 *.
::
rem Get the new file name into an environment variable
for %%f in (*) do set basename=%%f
::
rem Let't test it
echo The basename is %basename%
::
rem Back to the original directory
cd ..
::
rem Delete the auxiliary file
echo.| del tmpaux$$\*
::
rem Delete the auxiliary directory
rmdir tmpaux$$
::
rem Delete the environment variable
set basename=
::
goto _end
::
:_usage
echo Usage: %0 [FileNameWithExtension]
:_end
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:41 1996
Subject: Reading user's input
40. A batch to put user input into an environment variable
==========================================================
This definitely must be the neatest batch programming trick I have
ever seen. It is an adaptation of the batch published in Neil J.
Rubenking's User-to-User column in PC Magazine June 27, 1995, Vol.
14, No. 12, pp. 247-248. It is based on an idea by Tom Lavedas. It
will remedy the biggest (alleged) flaw in MS-DOS batch programming,
that is getting user input without any external programs. My
adaptation puts a simple word input into the INPUT_ environment
variable. The original inputs a whole sentence, but it is more
complicated. A single word (or a single letter) input is what is
usually sufficient in batch programming. The essence of the trick,
of you want to study it carefully to understand it, is in the fact
that the time command outputs the word "Enter" which features as an
auxiliary batch to be run by the SETINPUT.BAT below. An MS-DOS
version 3.3 or later is required.
@echo off
rem INPUT.BAT
echo This will copy your input to the environment variable INPUT_
echo Give your input:
fc con nul /lb1 /n | time | find " 1: "> setinput.bat
echo @echo off> enter.bat
echo set input_=%%4>> enter.bat
call setinput
del setinput.bat
del enter.bat
echo The value of INPUT_=%input_%
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:42 1996
Subject: Getting the last input parameter
41. Getting the last replaceable parameter
==========================================
As we know, batch files can use the so-called replaceable parameters
from %0 to %9. It is easy to get the first parameter in a batch
call. It is %1. (%0 gives the batch name). But what about getting
the last parameter when you do not know in advance how many
parameters the call has. Below is the code. It puts the last
parameter in the environment variable NF_. As an option, it also
puts the parameters from the first to the last but one into NF1_.
@echo off
rem INPUT.BAT
echo This will copy your input to the environment variable INPUT_
echo Give your input:
fc con nul /lb1 /n | date | find " 1: "> setinput.bat
echo @echo off> enter.bat
echo set input_=%%5>> enter.bat
call setinput
del setinput.bat
del enter.bat
echo The value of INPUT_=%input_%
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:43 1996
Subject: Creating an empty file
42. Creating an empty file if the file does not already exist
=============================================================
@echo off
if exist testfile goto _nocreate
rem > testfile
:_nocreate
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:44 1996
Subject: Handling disk's serial number
43. How can I change or remove the disk volume serial number?
=============================================================
Since version 4.0 the disk serial number was added to MS-DOS. When
you format a disk is it given a number like 4132-1DFF. It is
possible to change that information with an innovative batch file
alone. The batch by Bruce W. Shumway can be found in the PC Magazine
April 23, 1996, Vol. 15 No. 8, pp. 221-222. There also is a program
SETSER.EXE "Set the disk's serial number" by yours truly in the
ftp://garbo.uwasa.fi/pc/ts/ts5dos11.zip collection.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:45 1996
Subject: Inserting a delay
44. How to pause in a batch for a preset number of seconds?
===========================================================
You can use the MS-DOS CHOICE.COM command for the purpose as the
example below demonstrates
@echo off
echo Testing a delay, starting at ...
echo.| time | find /v "new"
choice /c:. /t:.,5 /n Pausing for five seconds
echo ending at ...
echo.| time | find /v "new"
The choice command was introduced with MS-DOS 6. If you have an
earlier MS-DOS version you can use my similar CHOOSE.EXE from
ftp://garbo.uwasa.fi/pc/ts/tsutlf15.zip.
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:46 1996
Subject: Batch compilers
45. Where can I find a program to compile batches into COMs or EXEs?
====================================================================
Since this question is so frequently asked I'll include an answer
into my batricks.txt information file. From Garbo program archive's
MS-DOS index file ftp://garbo.uwasa.fi/pc/INDEX.ZIP we can readily
locate the following files. Personally, I am dubious about batch
compilers and their complications. In my opinion, if one wants
distribute executables, it is much better to use a genuine
programming language like Turbo Pascal or C. I prefer batches in
their regular source format.
37419 Aug 10 1991 ftp://garbo.uwasa.fi/pc/pcmagutl/bat2ex15.zip
bat2ex15.zip Compile batch files to be executables, PC-Mag update
51299 Oct 31 1994 ftp://garbo.uwasa.fi/pc/batchutil/tbt324.zip
tbt324.zip TurboBAT Batch File Compiler, Foley Hi-Tech Systems
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:47 1996
Subject: Is a disk empty?
46. How can I test whether a disk is empty or not?
==================================================
This question is best answered by an annotated batch source:
@echo off
rem Provide help if no parameter is given.
if "%1"=="" goto _usage
rem Check that the input syntax was acceptable.
for %%f in (a b A B) do if "%1"=="%%f" goto _label1
goto _usage
rem See if "bytes free" appears in the directory listing as it will
rem if and only if there are files in the directory.
:_label1
dir %1:\ /s | find "bytes free" > r:\found.$$$
rem If "bytes free" was not found r:\found.$$$ file will be empty.
rem An empty file will not be copied.
copy r:\found.$$$ r:\notempty.$$$ > nul
rem If r:\found.$$$ was empty is was not copied, use this fact to test.
if exist r:\notempty.$$$ echo Disk %1: is not empty
if not exist r:\notempty.$$$ echo Disk %1: is empty
rem Delete the auxiliary files.
del r:\found.$$$
if exist r:\notempty.$$$ del r:\notempty.$$$
goto _out
:_usage
echo Usage: DSKEMPTY [DriveLetter]
echo e.g. DSKEMPTY A
echo Put no colon (:) after the DriveLetter!
:_out
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:00:48 1996
Subject: A different batch each day
47. How can I run a different batch depending on the weekday?
=============================================================
@echo off
::
rem Let's take care of everything by a single batch file.
rem First prepare a batch for each day. For brevity let's prepare
rem them for Monday and Tuesday days only.
::
echo echo It is Monday today and whatever else you may wish to do>mon.bat
echo echo It is Tuesday today and whatever else you may wish to do>tue.bat
::
rem The date command produces output like
rem Current date is Tue 27/08/1996
rem Enter new date (dd-mm-yy):
::
rem Utilize this fact by making a batch file tmp$$$.bat which in turn
rem runs the batch which is the third parameter (%3) of current.bat
rem (Tue.bat in the above).
echo.| date | find "Current">tmp$$$.bat
echo call %%3>current.bat
call tmp$$$.bat
::
rem Let's delete the tmp$$$.bat and current.bat files.
if exist current.bat del current.bat
if exist tmp$$$.bat del tmp$$$.bat
::
rem Since this was only a test, let's delete all the daily files, too.
if exist mon.bat del mon.bat
if exist tue.bat del tue.bat
--------------------------------------------------------------------
From ts@uwasa.fi Sun Sep 1 00:02:01 1996
Subject: Batch programming literature
Literature
==========
Most books on batch programming, which I have seen, are too
elementary to be really useful to the readers of this file. Hence
this list is very brief indeed.
Jamsa, Kris (1993). Concise Guide to MS-DOS Batch Files. Microsoft
Press. (Draws heavily on DEBUG, but might be of general interest
to you.)
Some issues of magazines like the PC Magazine and PC Computing have
contained much useful MS-DOS lore. But they have gradually become so
heavily Windows oriented that they are losing their interest and
usefulness to an MS-DOS user.